package com.shijie.service;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.imageio.ImageIO;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.parser.ParserDelegator;

import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor;

import com.shijie.component.tencent.TencentCloudCosClient;
import com.shijie.core.ServiceException;
import com.shijie.domain.entity.Magazines;
import com.shijie.domain.entity.Products;
import com.shijie.mapper.MagazinesMapper;
import com.shijie.mapper.ProductsMapper;
import com.shijie.utils.DateUtil;
import com.shijie.utils.PnWxMaQrcodeServiceImpl;

@Service
public class PictureSynthesisService {

	@javax.annotation.Resource
	private TencentCloudCosClient tencentCloudCosClient;
	@javax.annotation.Resource
	private MagazinesMapper magazinesMapper;
	@javax.annotation.Resource
	private ProductsMapper productsMapper;
	@Value("classpath:static/img/qrcode.png")
	private Resource qrcodeImg;
	@Value("classpath:static/img/logo.png")
	private Resource logoImg;
	@Autowired
	private WxMaService wxMaService;
	@Async
	public void syntherisPicture(Object obj) {
		if (obj instanceof Magazines) {
			Magazines m = (Magazines) obj;
			String url = this.createPictures(m.getId(),"m_" + m.getId(),
					m.getBannerUrl(), m.getTitle(), m.getPublicTime(),
					m.getSummary());
			if (!StringUtils.isEmpty(url)) {
				Magazines up = new Magazines();
				up.setPosterUrl(url);
				up.setId(m.getId());
				magazinesMapper.updateByPrimaryKeySelective(up);
			}
		} else if (obj instanceof Products) {
			Products m = (Products) obj;
			String url = this.createPictures(m.getId(),"p_" + m.getId(), m.getFocusUrl(),
					m.getTitle(), m.getCreateTime(), m.getSummary());
			if (!StringUtils.isEmpty(url)) {
				Products up = new Products();
				up.setPosterUrl(url);
				up.setId(m.getId());
				productsMapper.updateByPrimaryKeySelective(up);
			}
		}
	}

	private String createPictures(Integer id,String fileName, String bannelUrl,
			String title, Date publishTime, String content) {
		InputStream is  =null;
		InputStream inputStream =null;
		try {

			// 生成背景图
			BufferedImage bg = createBg(315, 480);
			// 添加顶部图片水印
			addImgWatermark(bg, ImageIO.read(new URL(bannelUrl)), 0, 0, 315,
					168);
			// 标题
			if (title.length() < 12) {
				bg = drawTextInImg(bg, title, 20, 184 + 30, 22, Font.BOLD);
			} else {
				title = title.substring(0, 12) + "...";
				bg = drawTextInImg(bg, title, 20, 184 + 30, 22, Font.BOLD);
			}
			// 日期
			bg = drawTextInImg(bg, DateUtil.toString(DateTime.now().toDate()),
					20, 217 + 18, 13, Font.PLAIN);

			// 内容
			List<String> list = getStrList(Html2Text.getContent(content), 20);
			for (int i = 0; i < list.size(); i++) {
				if (i > 5) {
					break;
				}
				if (i == 5 && list.get(i).length() >= 20) {
					String contentx = list.get(i).substring(0,
							list.get(i).length() - 3)
							+ "...";
					bg = drawTextInImg(bg, contentx, 20, 250 + (i + 1) * 20,
							14, Font.PLAIN);
				} else {
					bg = drawTextInImg(bg, list.get(i), 20, 250 + (i + 1) * 20,
							14, Font.PLAIN);
				}
			}

			// 添加logo
			addImgWatermark(bg, ImageIO.read(logoImg.getInputStream()), 20,
					417, 117, 38);
			File file = new PnWxMaQrcodeServiceImpl(wxMaService).createWxCodeLimit("id", "pages/search/search", 80, false, new WxMaCodeLineColor("0","0","0"));
			if(file==null || !file.exists()){
				throw new ServiceException("生成小程序码失败，请重试！");
			}
			
			is = new FileInputStream(file);
			// 添加小程序二维码
			addImgWatermark(bg, ImageIO.read(is), 215,
					380, 80, 80);

			ByteArrayOutputStream output = new ByteArrayOutputStream();
			ImageIO.write(bg, "png", output);
			inputStream = new ByteArrayInputStream(
					output.toByteArray());
			return tencentCloudCosClient.uploadFile2Cos(inputStream, fileName);
		} catch (Exception e) {
			throw new ServiceException(e.getMessage());
		}finally{
				try {
					if(is!=null){
						is.close();
					}
					if(inputStream!=null){
						inputStream.close();
					}
				} catch (IOException e) {
				}
			
		}
	}
	private void addImgWatermark(BufferedImage big, BufferedImage small,
			int left, int top, int width, int height) {
		try {
			Graphics2D g = big.createGraphics();
			g.drawImage(small, left, top, width, height, null);
			g.dispose();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private BufferedImage drawTextInImg(BufferedImage srcImg,
			String waterMarkContent, int x, int y, int fontSize, int fontBold) {
		Font font = new Font("Antique Olive Compact", fontBold, fontSize);
		try {
			// 读取原图片信息
			int srcImgWidth = srcImg.getWidth(null);// 获取图片的宽
			int srcImgHeight = srcImg.getHeight(null);// 获取图片的高
			// 加水印
			BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight,
					BufferedImage.TYPE_INT_RGB);
			Graphics2D g = bufImg.createGraphics();
			g.getDeviceConfiguration().createCompatibleImage(srcImgWidth,
					srcImgHeight, Transparency.TRANSLUCENT);
			g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
					RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
			g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
			g.setColor(Color.WHITE);
			g.setColor(Color.BLACK); // 根据图片的背景设置水印颜色
			g.setFont(font); // 设置字体
			// 设置水印的坐标
			g.drawString(waterMarkContent, x, y); // 画出水印
			g.dispose();
			return bufImg;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return srcImg;
	}

	private BufferedImage createBg(int width, int height) {
		BufferedImage bi = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);
		Graphics2D g2 = (Graphics2D) bi.getGraphics();
		g2.setBackground(Color.WHITE);
		g2.clearRect(0, 0, width, height);
		g2.setPaint(Color.RED);
		return bi;
	}

	private static class Html2Text extends HTMLEditorKit.ParserCallback {

		private static Html2Text html2Text = new Html2Text();

		StringBuffer s;

		public Html2Text() {
		}

		public void parse(String str) throws IOException {

			InputStream iin = new ByteArrayInputStream(str.getBytes());
			Reader in = new InputStreamReader(iin);
			s = new StringBuffer();
			ParserDelegator delegator = new ParserDelegator();
			// the third parameter is TRUE to ignore charset directive
			delegator.parse(in, this, Boolean.TRUE);
			iin.close();
			in.close();
		}

		public void handleText(char[] text, int pos) {
			s.append(text);
		}

		private String getText() {
			return s.toString();
		}

		private static String getContent(String str) {
			try {
				html2Text.parse(str);
			} catch (IOException e) {
				e.printStackTrace();
			}
			return html2Text.getText();
		}
	}

	/**
	 * 把原始字符串分割成指定长度的字符串列表
	 * 
	 * @param inputString
	 *            原始字符串
	 * @param length
	 *            指定长度
	 * @return
	 */
	private List<String> getStrList(String inputString, int length) {
		int size = inputString.length() / length;
		if (inputString.length() % length != 0) {
			size += 1;
		}
		return getStrList(inputString, length, size);
	}

	/**
	 * 把原始字符串分割成指定长度的字符串列表
	 * 
	 * @param inputString
	 *            原始字符串
	 * @param length
	 *            指定长度
	 * @param size
	 *            指定列表大小
	 * @return
	 */
	private List<String> getStrList(String inputString, int length, int size) {
		List<String> list = new ArrayList<String>();
		for (int index = 0; index < size; index++) {
			String childStr = substring(inputString, index * length,
					(index + 1) * length);
			list.add(childStr);
		}
		return list;
	}

	/**
	 * 分割字符串，如果开始位置大于字符串长度，返回空
	 * 
	 * @param str
	 *            原始字符串
	 * @param f
	 *            开始位置
	 * @param t
	 *            结束位置
	 * @return
	 */
	private String substring(String str, int f, int t) {
		if (f > str.length())
			return null;
		if (t > str.length()) {
			return str.substring(f, str.length());
		} else {
			return str.substring(f, t);
		}
	}
}
